package com.enation.app.javashop.core.member.service.impl;

import com.enation.app.javashop.core.distribution.exception.DistributionErrorCode;
import com.enation.app.javashop.core.distribution.exception.DistributionException;
import com.enation.app.javashop.core.distribution.model.enums.WithdrawStatusEnum;
import com.enation.app.javashop.core.goods.model.enums.Permission;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.model.dos.WithdrawBillDO;
import com.enation.app.javashop.core.member.model.dos.WithdrawRecordDO;
import com.enation.app.javashop.core.member.model.dto.WithdrawRecordQueryParam;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.member.service.WithdrawBillManager;
import com.enation.app.javashop.core.member.service.WithdrawRecordManager;
import com.enation.app.javashop.core.orderbill.model.dos.Bill;
import com.enation.app.javashop.core.orderbill.model.enums.BillStatusEnum;
import com.enation.app.javashop.core.orderbill.service.BillManager;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.security.model.Seller;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 提现记录
 * @author 孙建
 */
@Service
public class WithdrawRecordManagerImpl implements WithdrawRecordManager {

    @Autowired
    @Qualifier("memberDaoSupport")
    private DaoSupport memberDaoSupport;
    @Autowired
    private MemberManager memberManager;
    @Autowired
    private BillManager billManager;
    @Autowired
    private WithdrawBillManager withdrawBillManager;


    @Override
    public Page list(WithdrawRecordQueryParam withdrawRecordQueryParam) {
        List<Object> term = new ArrayList<>();
        StringBuilder sql = new StringBuilder("select * from es_withdraw_record where 1=1");

        // 卖家id
        Integer sellerId = withdrawRecordQueryParam.getSellerId();
        if(sellerId != null){
            sql.append(" and seller_id = ?");
            term.add(sellerId);
        }

        // 状态查询
        String status = withdrawRecordQueryParam.getStatus();
        if(!StringUtil.isEmpty(status)){
            sql.append(" and status = ?");
            term.add(status);
        }

        //关键字查询
        String keyword = withdrawRecordQueryParam.getKeyword();
        if (!StringUtil.isEmpty(keyword)) {
            sql.append(" and (member_name like ? or seller_name like ? " +
                    "or bank_name like ? or bank_account_name like ? or bank_number like ?) ");
            term.add("%" + keyword + "%");
            term.add("%" + keyword + "%");
            term.add("%" + keyword + "%");
            term.add("%" + keyword + "%");
            term.add("%" + keyword + "%");
        }

        // 申请时间查询
        Long startTime = withdrawRecordQueryParam.getStartTime();
        Long endTime = withdrawRecordQueryParam.getEndTime();
        if (startTime != null && endTime != null) {
            sql.append(" and apply_time between ? and ?");
            term.add(startTime);
            term.add(endTime);
        }
        sql.append(" order by apply_time desc");
        return this.memberDaoSupport.queryForPage(sql.toString(), withdrawRecordQueryParam.getPageNo(),
                withdrawRecordQueryParam.getPageSize(), WithdrawRecordDO.class, term.toArray());
    }

    /**
     * 申请提现
     */
    @Override
    @Transactional(value = "memberTransactionManager",propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
    public void applyWithdraw(WithdrawRecordDO withdrawRecordDO) {
        // 查询会员
        Member member = memberManager.getModel(withdrawRecordDO.getMemberId());
        // 补充申请参数
        withdrawRecordDO.setApplyTime(DateUtil.getDateline());
        withdrawRecordDO.setStatus(WithdrawStatusEnum.APPLY.name());
        Seller seller = UserContext.getSeller();
        withdrawRecordDO.setMemberName(member.getUname());
        withdrawRecordDO.setSellerId(seller.getSellerId());
        withdrawRecordDO.setSellerName(seller.getSellerName());
        this.memberDaoSupport.insert("es_withdraw_record", withdrawRecordDO);
        withdrawRecordDO.setId(memberDaoSupport.getLastId("es_withdraw_record"));

        // 查询结算单
        List<Bill> billList = billManager.listBySellerIdAndStatus(seller.getSellerId(), BillStatusEnum.PASS.name());

        // 修改结算单状态
        List<WithdrawBillDO> withdrawBillList = new ArrayList<>();
        for (Bill bill : billList) {
            billManager.editStatus(bill.getBillId(), Permission.SELLER);

            // 保存关系
            WithdrawBillDO withdrawBillDO = new WithdrawBillDO();
            withdrawBillDO.setBillId(bill.getBillId());
            withdrawBillDO.setWithdrawRecordId(withdrawRecordDO.getId());
            withdrawBillList.add(withdrawBillDO);
        }

        // 保存提现和结算单关系
        withdrawBillManager.batchSave(withdrawBillList);
    }


    /**
     * 提现审核
     */
    @Override
    @Transactional(value = "memberTransactionManager",propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
    public void auditing(Integer withdrawRecordId, String remark, String auditResult) {
        WithdrawRecordDO withdrawRecordDO = this.getModel(withdrawRecordId);
        if (withdrawRecordDO == null) {
            throw new ServiceException(DistributionErrorCode.E1004.code(), DistributionErrorCode.E1004.des());
        }
        //如果审核过
        if (withdrawRecordDO.getInspectTime() != null) {
            throw new ServiceException(DistributionErrorCode.E1002.code(), DistributionErrorCode.E1002.des());
        }
        if (StringUtil.isEmpty(auditResult)) {
            throw new ServiceException(DistributionErrorCode.E1005.code(), DistributionErrorCode.E1005.des());
        }
        // 审核时间
        long currTime = DateUtil.getDateline();
        // 审核失败
        if (auditResult.equals(WithdrawStatusEnum.FAIL_AUDITING.name())) {
            String applySql = "update es_withdraw_record set status=?,inspect_time=?,inspect_remark=? where id=?";
            this.memberDaoSupport.execute(applySql, auditResult, currTime, remark, withdrawRecordId);
            // 结算单状态还原到审核状态
            List<WithdrawBillDO> withdrawBillList = withdrawBillManager.listByWithdrawRecordId(withdrawRecordId);
            List<Integer> billIds = withdrawBillList.stream().map(WithdrawBillDO::getBillId).collect(Collectors.toList());
            List<Bill> billList = billManager.getByIds(billIds);
            for (Bill bill : billList) {
                billManager.previousStatus(bill, Permission.ADMIN);
            }
        //审核通过
        } else if (auditResult.equals(WithdrawStatusEnum.VIA_AUDITING.name())) {
            String applySql = "update es_withdraw_record set status=?,inspect_time=?,inspect_remark=? where id=?";
            this.memberDaoSupport.execute(applySql, auditResult, currTime, remark, withdrawRecordId);
        } else {
            throw new ServiceException(DistributionErrorCode.E1005.code(), DistributionErrorCode.E1005.des());
        }
    }

    /**
     * 转账
     */
    @Override
    @Transactional(value = "memberTransactionManager",propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
    public void transfer(Integer withdrawRecordId, String remark) {
        //如果审核过
        WithdrawRecordDO withdrawRecordDO = this.getModel(withdrawRecordId);
        if (withdrawRecordDO == null) {
            throw new ServiceException(DistributionErrorCode.E1004.code(), DistributionErrorCode.E1004.des());
        }
        if (withdrawRecordDO.getTransferTime() != null) {
            throw new DistributionException(DistributionErrorCode.E1002.code(), DistributionErrorCode.E1002.des());
        }
        String applySql = "update es_withdraw_record set status=?,transfer_time=?,transfer_remark=? where id=?";
        this.memberDaoSupport.execute(applySql, WithdrawStatusEnum.TRANSFER_ACCOUNTS.name(), DateUtil.getDateline(), remark, withdrawRecordId);

        // 结算单状态推进到下一个状态
        List<WithdrawBillDO> withdrawBillList = withdrawBillManager.listByWithdrawRecordId(withdrawRecordId);
        List<Integer> billIds = withdrawBillList.stream().map(WithdrawBillDO::getBillId).collect(Collectors.toList());
        List<Bill> billList = billManager.getByIds(billIds);
        for (Bill bill : billList) {
            bill.setPayTime(DateUtil.getDateline());
            billManager.nextStatus(bill, Permission.ADMIN);
        }
    }


    @Override
    public WithdrawRecordDO getModel(Integer id) {
        return this.memberDaoSupport.queryForObject(WithdrawRecordDO.class, id);
    }

}
